#pragma once

#include "bcs/BoundaryCondition.h"
#include "base/WrapperVtkmTypes.h"

struct FarFieldBC
{
	using ValueType = vtkm::Vec<FloatDefault, 5>;

	ValueType _ul;
	Vec3f _normal;
	FloatDefault _gamma = 1.4;
	FloatDefault _rho_inf = 1;
	FloatDefault _p_inf = 1;
	Vec3f _vel_inf = { 1,0,0 };

	ValueType Execute(const ValueType& ul, const Vec3f& normal)
	{
		ValueType ur;
		FloatDefault vn = ul[1] * normal[0] + ul[2] * normal[1] + ul[3] * normal[2];
		ur[0] = ul[0];
		ur[1] = ul[1] - 2 * vn * normal[0];
		ur[2] = ul[2] - 2 * vn * normal[1];
		ur[3] = ul[3] - 2 * vn * normal[2];
		ur[4] = ul[4];

		return ur;
	}

	void SubSonicInlet()
	{
		//ValueType ur;
		//ur[0] = _rho_inf;
		//ur[1] = _rho_inf * _vel_inf[0];
		//ur[2] = _rho_inf * _vel_inf[1];
		//ur[3] = _rho_inf * _vel_inf[2];
		//ur[4] = p/ (_gamma - 1) + 0.5 * _rho_inf * vtkm::MagnitudeSquared(_vel_inf);
	}

	void SubSonicOutlet()
	{

	}

	void SuperSonicInlet()
	{
		ValueType ur;
		ur[0] = _rho_inf;
		ur[1] = _rho_inf * _vel_inf[0];
		ur[2] = _rho_inf * _vel_inf[1];
		ur[3] = _rho_inf * _vel_inf[2];
		ur[4] = _p_inf / (_gamma - 1) + 0.5 * _rho_inf * vtkm::MagnitudeSquared(_vel_inf);
	}
	void SuperSonicOutlet()
	{
		ValueType ur;
		ur = _ul;
	}
};